import {
  Engine,
  Render,
  Runner,
  Common,
  MouseConstraint,
  Composite,
  Composites,
  Mouse,
  World, 
  Events,
  Body, 
  Bodies
} from 'Matter'

export default () => {

  let // create engine
    engine = Engine.create({
      world: World.create(
        {
          gravity: {
            x: 0,
            y: 0
          }
        }
      )
    }),
    world = engine.world

  console.log('engine', engine)

  let // create renderer
    render = Render.create({
      element: document.body,
      engine: engine,
      options: {
        background: '#fff',
        width: 750,
        height: 1334,
        wireframes: false,
        showVelocity: true
      }
    }),
    canvas = render.canvas

  canvas.style.position = 'absolute'
  canvas.style.top = canvas.style.left = 0
  canvas.style.width = canvas.style.height = '100%'

  Render.run(render)

  let // create runner
    runner = Runner.create()

  Runner.run(runner, engine)

  World.add(world, Composites.stack(0, 0, 10, 5, 48, 50, (x, y) => {
    return Bodies.circle(x, y, 20, {
      restitution: 1,
      render: {
        lineWidth: 0,
        sprite: {
          texture: require('./bg.jpg'),
          xScale: 0.12,
          yScale: 0.12
        }
      }
    })
  }))

  World.add(world, [
    Bodies.rectangle(canvas.width, -100, canvas.width * 2, 200, { // top
      isStatic: true,
    }),
    Bodies.rectangle(canvas.width, 100 + canvas.height, canvas.width * 2, 200, { // bottom
      isStatic: true,
    }),
    Bodies.rectangle(-100, canvas.height, 200, canvas.height * 2, { // left
      isStatic: true,
    }),
    Bodies.rectangle(100 + canvas.width, canvas.height, 200, canvas.height * 2, { // right
      isStatic: true,
    }),
  ])

  let // add mouse control
    mouse = Mouse.create(render.canvas),
    mouseConstraint = MouseConstraint.create(engine, {
      mouse: mouse,
      constraint: {
        stiffness: 0.3,
        render: {
          visible: true
        }
      }
    })

  World.add(world, mouseConstraint)

  // keep the mouse in sync with rendering
  // render.mouse = mouse

  // fit the render viewport to the scene
  // Render.lookAt(render, {
  //   min: { x: 0, y: 0 },
  //   max: { x: 1334, y: 768 }
  // })


  Events.on(mouseConstraint, 'mousedown', function (event) {
    let mousePosition = event.mouse.position;
    console.log('mousedown at ' + mousePosition.x + ' ' + mousePosition.y);
    shakeScene(engine);
  });

  Events.on(mouseConstraint, 'mouseup', function (event) {
    let mousePosition = event.mouse.position;
    console.log('mouseup at ' + mousePosition.x + ' ' + mousePosition.y);
  });

  Events.on(mouseConstraint, 'startdrag', function (event) {
    console.log('startdrag', event);
  });

  Events.on(mouseConstraint, 'enddrag', function (event) {
    console.log('enddrag', event);
  })


  Events.on(world, 'afterAdd', event => {
    console.log('added to world:', event.object);
  })
  Events.on(engine, 'beforeUpdate', event => {
    let engine = event.source;
    // console.log(event)
    // apply random forces every 5 secs
    if (event.timestamp % 4500 < 50) shakeScene(engine);
  })

  // shakeScene(engine);

  Events.on(engine, 'collisionStart', event => {
    let pairs = event.pairs;
    pairs.forEach(pair => {
      pair.bodyA.render.fillStyle = 'red';
      pair.bodyB.render.fillStyle = 'red';
    })
  })
  // Events.on(engine, 'collisionActive', function (event) {
  //   let pairs = event.pairs;
  //   pairs.forEach(pair => {
  //     pair.bodyA.render.fillStyle = '#333';
  //     pair.bodyB.render.fillStyle = '#333';
  //   })
  // })
  Events.on(engine, 'collisionEnd', function (event) {
    let pairs = event.pairs;
    pairs.forEach(pair => {
      pair.bodyA.render.fillStyle = '#222';
      pair.bodyB.render.fillStyle = '#222';
    })
  })

  function shakeScene(engine) {
    let bodies = Composite.allBodies(engine.world);
    bodies.forEach(body => {
      if (!body.isStatic) {
        let forceMagnitude = 0.02 * body.mass;
        Body.applyForce(body, body.position, {
          x: (forceMagnitude + Common.random() * forceMagnitude) * Common.choose([1, -1]),
          y: body.position.y > canvas.height / 2 ? -forceMagnitude - Common.random() * forceMagnitude : forceMagnitude + Common.random() * forceMagnitude
        })
      }
    })
  }


}